#include "head.h"


static int long_command_handler(int net_fd, transmit_t* ptransmit,shared_resource_t* pshared_resource);
static int short_command_handler(int net_fd, transmit_t* ptransmit,shared_resource_t* pshared_resource);


// require_handler 函数返回-1证明请求有问题，服务端会移除监听网络文件描述符
// 所以，如果登录注册或者长短命令处理函数处理时，发现客户端有问题，应该返回-1
int require_handler(int net_fd, shared_resource_t* pshared_resource,
                   MYSQL* mysql, int epoll_fd, 
                   hash_map_t* hash_map, timeout_node_t** timeout_queue)
{
    transmit_t transmit;
    bzero(&transmit,sizeof(transmit));
    int ret = recv(net_fd,&transmit,sizeof(transmit),MSG_WAITALL);

    // 说明对端关闭了连接
    if(ret == 0){ return -1;}

    if(strcmp(transmit.flag,"LOGIN") == 0){
        // 登录逻辑
        //printf("进入了服务端登录逻辑\n");
        int ret_login=login_server_handler(mysql,net_fd,&transmit);
        if(ret_login==1)
        {
            char session[256] = {0};
            sprintf(session,"%s 登陆失败\n",transmit.name);
            LOG(INFO,session);
            return 0;//无论成功失败都要返回0，返回1会直接踢出通信；
        }
        char session[256] = {0};
        sprintf(session,"%s %s\n",transmit.name, transmit.flag);
        LOG(INFO,session);
        return 0;
    }
    if(strcmp(transmit.flag,"REGISTER") == 0){
        // 注册逻辑
        // printf("进入了服务端注册逻辑\n");
        int ret_register=register_server_handler(mysql,net_fd,&transmit);
        if(ret_register==1)
        {
            char session[256] = {0};
            sprintf(session,"%s 注册失败\n",transmit.name);
            LOG(INFO,session);
            return 0;
        }
        char session[256] = {0};
        sprintf(session,"%s %s\n",transmit.name, transmit.flag);
        LOG(INFO,session);
        return 0;

    }

    // token 验证，如果token验证不通过，给客户端发送 "登陆超时，请重新登录"
    int ret_token = decrypt_token(&transmit,net_fd);
    if(ret_token == -1){return -1;}
    // 通过token字符串获取用户名，获取到的用户名存储的transmit的name字段

    char session[256] = {0};
    sprintf(session,"%s %s %s\n",transmit.name,transmit.command,transmit.argument);
    LOG(INFO,session);
    LOG(WARING,session);
    LOG(ERROR,session);

    
    if(strcmp(transmit.flag,"SHORTCOMMAND") == 0){
        return short_command_handler(net_fd,&transmit,pshared_resource);
    }
    if(strcmp(transmit.flag,"LONGCOMMAND") == 0){
        // 因为这里是长命令，上传和下载，需要长时间通信，不要监听对端的网络描述符
        int index = 0;
        hash_map_del(hash_map, net_fd, &index);
        timeout_del(timeout_queue, net_fd, index);      
        epoll_del(epoll_fd, net_fd);
        return long_command_handler(net_fd,&transmit,pshared_resource);
    }


    return 0;
}


int short_command_handler(int net_fd, transmit_t* ptransmit,shared_resource_t* pshared_resource){
    client_info_t client_info;
    bzero(&client_info,sizeof(client_info));

    client_info.net_fd = net_fd;
    strcpy(client_info.name ,ptransmit->name);
    strcpy(client_info.command ,ptransmit->command);
    strcpy(client_info.argument ,ptransmit->argument);

    pthread_mutex_lock(&(pshared_resource->task_queue_mutex));
    en_task_queue(&(pshared_resource->task_queue),&client_info);
    // 这里需要使用条件变量唤醒阻塞的子线程;
    pthread_cond_broadcast(&(pshared_resource->task_queue_cond));
    pthread_mutex_unlock(&(pshared_resource->task_queue_mutex));


    return 0;
}

int long_command_handler(int net_fd, transmit_t* ptransmit,shared_resource_t* pshared_resource){
    client_info_t client_info;
    bzero(&client_info,sizeof(client_info));

    client_info.net_fd = net_fd;
    strcpy(client_info.name ,ptransmit->name);
    strcpy(client_info.command ,ptransmit->command);
    strcpy(client_info.argument ,ptransmit->argument);

    pthread_mutex_lock(&(pshared_resource->task_queue_mutex));
    en_task_queue(&(pshared_resource->task_queue),&client_info);
    // 这里需要使用条件变量唤醒阻塞的子线程;
    pthread_cond_broadcast(&(pshared_resource->task_queue_cond));
    pthread_mutex_unlock(&(pshared_resource->task_queue_mutex));


    return 0;
}

